package com.bw.aop;

import com.alibaba.fastjson.JSON;
import com.bw.annotation.Log;
import com.bw.domain.OperLog;
import com.bw.enums.BusinessType;
import com.bw.enums.OperType;
import com.bw.service.OperLogService;
import com.bw.utils.html.EscapeUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpServletRequest;
import javax.websocket.Session;
import java.util.Date;

/**
 * @author Big-Hang
 * @data 2023/8/17
 */
@Configuration
@Aspect
public class OperLogAop  {

    @Autowired
    HttpServletRequest request;
    @Autowired
    OperLogService operLogService;

    //@annotation 用于匹配当前执行方法持有指定注解的方法
    @Around("@annotation(com.bw.annotation.Log)&& @annotation(log)")
    //ProceedingJoinPoint 对象是JoinPoint的子接口,该对象只用在@Around的切面方法中,
    public Object aop(ProceedingJoinPoint pjp, Log log) throws Throwable {
        //代理对象
        Signature signature = pjp.getSignature();


        OperLog operLog = new OperLog();

        String name = signature.getName();
        System.out.println("操作方法:"+name);


        operLog.setOperIp(operIp(request));
        System.err.println("ip:"+operIp(request));

        operLog.setOperTime(new Date());
        System.err.println("操作时间:"+new Date());

//        Object o = JSON.toJSON(jsonResult);
//        System.out.println("jsonResult："+o);

        //操作url   /operLog/delete
        String operUrl = request.getRequestURI();
        System.err.println("operUrl:"+operUrl);
        operLog.setOperUrl(operUrl);

        // 设置方法名称
        String className = pjp.getTarget().getClass().getName();
        String methodName = pjp.getSignature().getName();
        System.err.println("className:"+className + "."+methodName+"()");
        operLog.setMethod(className + "."+methodName + "()");

        //请求方式
        String requestMethod = request.getMethod();
        System.err.println("requestMethod:"+requestMethod);
        operLog.setRequestMethod(requestMethod);

        String businessType = log.businessType().toString();
        System.err.println("businessType:"+businessType);
        operLog.setBusinessType(businessType);

        String operType = log.operType().toString();
        System.err.println("operType:"+operType);
        operLog.setOperType(operType);

        String title = log.title();
        System.err.println("title:"+title);
        operLog.setTitle(title);

        //获取参数
        String params = param(pjp.getArgs());
        System.err.println("params:"+params);
        operLog.setOperParam(params);

        //需要在前端过滤器写入这句 ↓ ↓ ↓ ↓
        //config.headers['username'] = sessionStorage.getItem('username');
        // 从请求头中获取 登录用户名
        String operName = request.getHeader("username");
        System.out.println("operName:"+operName);
        operLog.setOperName(operName);

        System.out.println("name:+++"+request.getParameterNames());
        System.out.println("url:===="+request.getRequestURL());



        Object target = pjp.getTarget();

        Object proceed = pjp.proceed();

        operLogService.save(operLog);

        return proceed;
    }

    /**
     * 操作参数
     */
    private   String param(Object[] arrayParam){
        String params="";
        if (arrayParam != null && arrayParam.length >0){
            for (int i = 0; i < arrayParam.length; i++) {
                Object json = JSON.toJSON(arrayParam[i]);
                //(+= 会对右边进行强制转换为左边类型)
                params += json;
            }
        }
        return params;
    }

    /**
     * ip地址
     * @param request
     * @return
     */
    public String operIp(HttpServletRequest request){
        String ip = request.getLocalAddr();
        //如果是 0:0:0:0:0:0:0:1 表示本机，则返回 127.0.0.1
        return  "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : EscapeUtil.clean(ip);
    }



}
